import time
import json
import hmac
import urllib
from urllib.parse import parse_qs, urlencode
import base64
import requests
from flask import Blueprint
from flask_restful import Api, Resource, reqparse
from flask import current_app
from models import db
from utils.cxsjgs.cxsjgs import cxsjgs_json
from werkzeug.security import generate_password_hash, check_password_hash
from utils.jwt_util import _generate_token
from models.user import OAuthUserModel, UserModels

init_bp = Blueprint('init', __name__, url_prefix='/oauth')
# 创建蓝图的主入口
api = Api(init_bp)


# 统一后端返回给前端的数据结构
@api.representation('application/json')
def output_json(data, code, headers=None):
    resp = cxsjgs_json(data, code)
    return resp


class DingDingResource(Resource):

    def dingding_user(self, code):
        """获取扫码登录的用户信息"""
        appid = current_app.config.get('APP_ID')
        appSecret = current_app.config.get('APP_SECRET')
        timestamp = str(int(time.time() * 1000))
        signature = base64.b64encode(
            hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod="sha256").digest())
        base_url = "https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature="
        url = base_url + urllib.parse.quote(signature.decode('utf-8')) + "&timestamp="+timestamp + "&accessKey=" + appid
        js = json.dumps({'tmp_auth_code': code})
        try:
            resp = requests.post(url, js, headers={'Content-Type': 'application/json'})
            print("resp>>>", resp.json())
        except Exception as e:
            print(e)
            return {'code': 500, "message": 'post 获取钉钉用户信息失败'}
        user_info = resp.json()
        if user_info['errcode'] != 0:
            return {'code': 500, "message": '根据code获取钉钉用户信息失败'}
        info_dict = user_info['user_info']
        return info_dict

    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('code')
        args = parser.parse_args()
        code = args.get('code')
        print('code>>>>', code)
        user_info = self.dingding_user(code)
        openid = user_info['openid']
        oauth_user_ = OAuthUserModel.query.filter_by(oauth_id=openid).first()
        print("oauth_user>>>>1", oauth_user_)
        if oauth_user_:
            print("oauth_user>>>>2", oauth_user_)
            user = UserModels.query.filter_by(uid=oauth_user_.user).first()
            payload = {
                'user_id': user.uid,
                'username': user.account
            }
            token, token_ = _generate_token(payload)
            return {'code': 200, "account": user.account, 'uid': user.uid, "token": token}
        else:
            return {"message": "没有绑定用户，请先绑定", 'uid': openid}


class DingDingUser(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('account')
        parser.add_argument('password')
        parser.add_argument('unid')
        args = parser.parse_args()
        account = args.get('account')
        pwd = args.get('password')
        unid = args.get('unid')
        user = UserModels.query.filter_by(account=account).first()
        if not user:
            return {"message": "用户未注册", "code": 400}
        else:
            pwd_ = check_password_hash(user.password, pwd)
            if not pwd_:
                return {"message": "密码不正确", "code": 400}
            rest = OAuthUserModel(oauth_id=unid, user=user.uid, oauth_type="dingding")
            db.session.add(rest)
            db.session.commit()
            payload = {
                'user_id': user.uid,
                'username': user.account
            }
            token, token_ = _generate_token(payload)
            rest_data = {
                'username': user.account,
                'token': token,
                'uid': user.uid
            }
            print("dingding绑定成功")
            return {"message": "绑定成功", "code": 200, "data": rest_data}


class WeiboResource(Resource):
    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('code')
        args = parser.parse_args()
        code = args.get('code')
        base_url = 'https://api.weibo.com/oauth2/access_token'
        data_ = {
            "client_id": current_app.config.get('WEIBO_APP_ID'),
            "client_secret": current_app.config.get('WEIBO_APP_SECRET'),
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": "http://127.0.0.1:8080/weibo"
        }
        try:
            resp = requests.post(url=base_url, data=data_)
            print("resp=========>", resp.json())
        except Exception as e:
            print(e)
            return {'code': 500, "message": 'post 获取微博用户信息失败'}
        access_token = resp.json()['access_token']
        print("access_token>>>>", access_token)

        if not access_token:
            return {'code': 500, "message": 'post 根据token获取微博用户信息失败'}
        else:
            oauth_user_ = OAuthUserModel.query.filter_by(oauth_id=access_token, oauth_type="weibo").first()
            if oauth_user_:
                print("oauth_user>>>>2", oauth_user_)
                user = UserModels.query.filter_by(uid=oauth_user_.user).first()
                payload = {
                    'user_id': user.uid,
                    'username': user.account
                }
                token, token_ = _generate_token(payload)
                return {'code': 200, "account": user.account, 'uid': user.uid, "token": token}
            else:
                return {"message": "没有绑定用户，请先绑定", 'uid': access_token}
# 闪耀的名人威光


class WeiboUser(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('account')
        parser.add_argument('password')
        parser.add_argument('unid')
        args = parser.parse_args()
        account = args.get('account')
        pwd = args.get('password')
        unid = args.get('unid')
        user = UserModels.query.filter_by(account=account).first()
        if not user:
            return {"message": "用户未注册", "code": 400}
        else:
            pwd_ = check_password_hash(user.password, pwd)
            if not pwd_:
                return {"message": "密码不正确", "code": 400}
            rest_ = OAuthUserModel(oauth_id=unid, user=user.uid, oauth_type="weibo")
            db.session.add(rest_)
            db.session.commit()
            payload = {
                'user_id': user.uid,
                'username': user.account
            }
            token, token_ = _generate_token(payload)
            rest_data = {
                'username': user.account,
                'token': token,
                'uid': user.uid
            }
            print("weibo绑定成功")
            return {"message": "绑定成功", "code": 200, "data": rest_data}


api.add_resource(DingDingResource, '/dingding')
api.add_resource(DingDingUser, '/dingding/bind')
api.add_resource(WeiboResource, '/weibo')
api.add_resource(WeiboUser, '/weibo/bind')


